Skip to content

refactor: combining shared code markdown renderer readme & changelog #2717

Open
WilcoSp wants to merge 242 commits into
npmx-dev:mainfrom
WilcoSp:feat/markdown-kit
Open

refactor: combining shared code markdown renderer readme & changelog #2717
WilcoSp wants to merge 242 commits into
npmx-dev:mainfrom
WilcoSp:feat/markdown-kit

Conversation

@WilcoSp
Copy link
Copy Markdown
Contributor

@WilcoSp WilcoSp commented May 11, 2026

click here to preview pr

🔗 Linked issue

This pr is part of #501

🧭 Context

Currently changelog uses a seperate marked markdown renderer from readme, this pr takes the shared code and makes it into a "markdown kit" so that code that can be shared will be shared

📚 Description

Moves shared code for both changelog & readme to a shared markdown kit while still allowing for each to have their unique needs.

additional changes

  • Heading have been changed to be more consistent and easier to use by users to the following:
    ## heading -> <hx><a href="#...>heading</a></hx>
    ## [Example](https://example.com) -> <hx><a href="https://example.com">Example</a><a href="#...></a></hx>
  • Tests have been added for the changelog markdown renderer for what not shared or changed for changelog.
  • Thanks to the tests also some bugs have been fixed.
  • Also for changelog.md the jumping to the requested version has been fixed, now if "3.5.1" is requested then "3.5.11" won't be selected.
  • 502 will now only be returned when ungh.cc is exhausted, others have been changed to 500
  • at package.takumi.vue & externallinks.vue the provider icons are now given via the useProviderIcon composable
  • change the unocss config to include useProviderIcon composable
  • fixed a bug to where when switching between package tabs that the message "package doesn't have changelogs" is being shown while earlier it did have it.
  • changed how the skeleton loaders is shown in package changelog, now pending is being used from useLazyFetch in the ChangelogReleases & ChangelogMarkdown components instead of using <suspense> at the package-changelog page, this should remove/reduce the blank screen between showing the skeleton laoders & showing data.
  • each release has now a direct link to the original release on github (and future git providers)
  • adding version_distribution_title translation and fixing a typo for Dutch (nl.json)
  • some further smaller refactors

AI usage

For app/utils/header-version-matcher.ts I've used Gemini to get the regex for matching more exact the requested version in a toc item text

notes

The branch of this pr was based on #1233 initially, that's why there are so many commits, file changes does show correctly what has changed

the createLink factory function will receive in future PRs changes, due to future plans to format git links to #pr, @person etc

WilcoSp and others added 30 commits February 4, 2026 21:17
excludes changelog releases due to needing api calls
…gelog info endpoint will return ChangelogMarkdownInfo instead of ChangelogReleaseInfo
@gameroman gameroman added the needs review This PR is waiting for a review from a maintainer label May 15, 2026
@WilcoSp
Copy link
Copy Markdown
Contributor Author

WilcoSp commented May 15, 2026

for #2717 (review)
this is on purpose because it prevents flashing the skeleton loader when switching versions by using the previous result from useLazyFetch while checking for new info.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
app/components/Changelog/Card.vue (1)

24-27: ⚡ Quick win

Drop the non-null assertion on inject and supply a safe default.

inject<{...}>('changelog-provider-linkattr')! only affects TypeScript; if any future caller (tests, Storybook, another consumer) renders Card.vue without the parent providing 'changelog-provider-linkattr', the destructuring will throw at runtime. Either provide a default object or guard the destructuring so the card degrades gracefully.

♻️ Suggested refactor
-const { providerIcon, viewOnProvider } = inject<{
-  providerIcon: ComputedRef<IconClass>
-  viewOnProvider: ComputedRef<string>
-}>('changelog-provider-linkattr')!
+const injected = inject<{
+  providerIcon: ComputedRef<IconClass>
+  viewOnProvider: ComputedRef<string>
+} | null>('changelog-provider-linkattr', null)
+const providerIcon = computed(() => injected?.providerIcon.value)
+const viewOnProvider = computed(() => injected?.viewOnProvider.value)

You can then v-if="providerIcon" around the LinkBase to skip rendering when the context is absent.

Also consider using a typed InjectionKey<...> exported from a shared module instead of a raw string — it removes the need to repeat the generic at every call site and prevents key drift between provider and consumer.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/Changelog/Card.vue` around lines 24 - 27, The inject call in
Card.vue uses a non-null assertion (inject<...>('changelog-provider-linkattr')!)
which can throw at runtime if the provider is missing; change it to supply a
safe default or guard the result before destructuring: call
inject('changelog-provider-linkattr') without the bang, check for null/undefined
and fall back to a default object providing safe ComputedRefs for providerIcon
and viewOnProvider, then only render the LinkBase when providerIcon is present
(e.g., v-if="providerIcon"); optionally replace the raw string key with an
exported typed InjectionKey to keep provider/consumer keys consistent
(referencing providerIcon, viewOnProvider, inject, and
'changelog-provider-linkattr').
app/pages/package-changelog/[[org]]/[name].vue (2)

141-185: ⚡ Quick win

Remove the commented-out <Suspense> block instead of leaving it inline.

Per the PR objectives the Suspense-based loading was intentionally replaced with useLazyFetch's pending inside ChangelogReleases/ChangelogMarkdown. Leaving ~45 lines of commented template (lines 141–185) creates noise, hides the actual control flow (the v-if/v-else-if chain reads awkwardly with comments interleaved), and will rot quickly. Git history is sufficient for recovery.

♻️ Suggested cleanup
-      <!-- <Suspense v-else-if="changelog"> 
-        <template `#default`>-->
-      <LazyChangelogReleases
+      <LazyChangelogReleases
         v-if="changelog?.type === 'release'"
         :info="changelog"
@@
         />
       </LazyChangelogMarkdown>
-      <!-- </template>
-        <template `#fallback`>
-          <section class="flex flex-col gap-2 py-3">
-            <SkeletonBlock class="h-8 w-40 rounded" />
-            <ul class="ms-3 list-disc my-[1rem] ps-[1.5rem] marker:color-border-hover">
-              <li class="mb-1" v-for="_n in 5">
-                <SkeletonBlock class="h-7 w-full max-w-2xl rounded" />
-              </li>
-            </ul>
-
-            <SkeletonBlock class="h-5 w-5/6 max-w-2xl rounded" />
-            <SkeletonBlock class="h-5 w-3/4 max-w-2xl rounded" />
-          </section>
-        </template>
-      </Suspense> -->
       <!-- error handling -->
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/pages/package-changelog/`[[org]]/[name].vue around lines 141 - 185,
Remove the large commented-out Suspense block and its inner fallback template so
the template contains only the active v-if/v-else-if chain; delete the commented
"<Suspense> ... </Suspense>" section wrapping (and any commented fallback
markup) that surrounds the LazyChangelogReleases and LazyChangelogMarkdown
usage, leaving the LazyChangelogReleases, LazyChangelogMarkdown and their
LazyChangelogErrorMsg children intact; ensure no other logic relies on that
Suspense wrapper (the components ChangelogReleases/ChangelogMarkdown now handle
loading via useLazyFetch pending) and run a quick lint/format pass to confirm
the template remains valid.

151-170: 💤 Low value

Rename viewOnGit prop to viewOnProvider in ChangelogErrorMsg component for consistency.

The variable was renamed to generic provider terminology in line 51 (viewOnProvider), but the component's prop on lines 154 and 168 still uses :viewOnGit="viewOnProvider". Update the prop name in app/components/Changelog/ErrorMsg.vue to maintain uniform abstraction.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/pages/package-changelog/`[[org]]/[name].vue around lines 151 - 170, The
Changelog error component still defines/accepts the old prop name viewOnGit
while callers (LazyChangelogErrorMsg) pass viewOnProvider; open
app/components/Changelog/ErrorMsg.vue and rename the prop from viewOnGit to
viewOnProvider (keep the same type/default/behavior), update any internal
references in the component (props destructuring, template bindings, methods) to
use viewOnProvider, and ensure the component export/props declaration matches
the new name so the usages at lines where LazyChangelogErrorMsg is rendered work
consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@app/components/Changelog/Card.vue`:
- Around line 24-27: The inject call in Card.vue uses a non-null assertion
(inject<...>('changelog-provider-linkattr')!) which can throw at runtime if the
provider is missing; change it to supply a safe default or guard the result
before destructuring: call inject('changelog-provider-linkattr') without the
bang, check for null/undefined and fall back to a default object providing safe
ComputedRefs for providerIcon and viewOnProvider, then only render the LinkBase
when providerIcon is present (e.g., v-if="providerIcon"); optionally replace the
raw string key with an exported typed InjectionKey to keep provider/consumer
keys consistent (referencing providerIcon, viewOnProvider, inject, and
'changelog-provider-linkattr').

In `@app/pages/package-changelog/`[[org]]/[name].vue:
- Around line 141-185: Remove the large commented-out Suspense block and its
inner fallback template so the template contains only the active v-if/v-else-if
chain; delete the commented "<Suspense> ... </Suspense>" section wrapping (and
any commented fallback markup) that surrounds the LazyChangelogReleases and
LazyChangelogMarkdown usage, leaving the LazyChangelogReleases,
LazyChangelogMarkdown and their LazyChangelogErrorMsg children intact; ensure no
other logic relies on that Suspense wrapper (the components
ChangelogReleases/ChangelogMarkdown now handle loading via useLazyFetch pending)
and run a quick lint/format pass to confirm the template remains valid.
- Around line 151-170: The Changelog error component still defines/accepts the
old prop name viewOnGit while callers (LazyChangelogErrorMsg) pass
viewOnProvider; open app/components/Changelog/ErrorMsg.vue and rename the prop
from viewOnGit to viewOnProvider (keep the same type/default/behavior), update
any internal references in the component (props destructuring, template
bindings, methods) to use viewOnProvider, and ensure the component export/props
declaration matches the new name so the usages at lines where
LazyChangelogErrorMsg is rendered work consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d2996937-03cf-43bc-ac75-a25809c790e4

📥 Commits

Reviewing files that changed from the base of the PR and between c335353 and 568acc2.

📒 Files selected for processing (4)
  • app/components/Changelog/Card.vue
  • app/pages/package-changelog/[[org]]/[name].vue
  • server/api/changelog/releases/[provider]/[owner]/[repo].get.ts
  • shared/types/changelog.ts
✅ Files skipped from review due to trivial changes (1)
  • server/api/changelog/releases/[provider]/[owner]/[repo].get.ts

…nge by ungh.cc

added version_distribution_title translation to Dutch
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 30, 2026

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
i18n/locales/nl.json Localization changed, will be marked as complete. 🔄️
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@i18n/locales/nl.json`:
- Line 719: The translation string for the weekly downloads title has a typo:
update the value of the "version_distribution_title" key to use "Wekelijkse"
instead of "Weekelijkse" so the user-facing label reads "Wekelijkse downloads
voor versie {version}" (edit the JSON value for the version_distribution_title
entry).

In `@uno.config.ts`:
- Around line 36-40: The UnoCSS include currently references
'./src/composables/useProviderIcon.ts' but the project imports the module as
'~/composables/useProviderIcon' (the useProviderIcon composable) and UnoCSS
therefore isn't scanning the actual module; update the include array in
uno.config.ts to reference the same module used by imports (e.g. replace
'./src/composables/useProviderIcon.ts' with '~/composables/useProviderIcon' or
the correct module alias used in your code) so UnoCSS will scan useProviderIcon
and generate the provider icon classes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5acb90f1-35a2-41d1-8ac1-2ec96b642f6e

📥 Commits

Reviewing files that changed from the base of the PR and between 568acc2 and 4ef1d58.

📒 Files selected for processing (8)
  • app/components/Changelog/Card.vue
  • app/components/Package/Header.vue
  • app/pages/package-changelog/[[org]]/[name].vue
  • i18n/locales/nl.json
  • server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts
  • server/utils/changelog/detectChangelog.ts
  • test/nuxt/a11y.spec.ts
  • uno.config.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • app/components/Changelog/Card.vue
  • test/nuxt/a11y.spec.ts
  • server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts
  • app/components/Package/Header.vue

Comment thread i18n/locales/nl.json Outdated
Comment thread uno.config.ts
@WilcoSp
Copy link
Copy Markdown
Contributor Author

WilcoSp commented May 30, 2026

I've just fixed a small issue with git provider icons not showing (for example codeberg), this happened because all the icons where moved to the useProviderIcon composable instead of being inside the .vue files.

I've just committed a fix that now includes the useProviderIcon into unocss's config (commits: 4ef1d58 & 4487bc1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs review This PR is waiting for a review from a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants